#include "type.h"

#include <cxxabi.h>
#include <stdlib.h>

using namespace core;

const TypeValue Type::INVALID_VALUE = "TInvalid";
const TypeName Type::INVALID_NAME = "TNInvalid";

Type::Type() : m_operations()
{

}

Type::~Type()
{

}

QString Type::name() const
{
    const QString name(demangledName(typeid(*this).name()));

    return name;
}

bool Type::matches(const Type& type) const
{
    const QString name(demangledName(typeid(*this).name()));
    const QString otherName(demangledName(typeid(type).name()));

    return name == otherName;
}

bool Type::matches(const TypeName& name) const
{
    const QString thisName(demangledName(typeid(*this).name()));

    return thisName == name;
}

bool Type::supports(const OperationName& name) const
{
    return m_operations.contains(name);
}

QSet<OperationName> Type::supportedOperations() const
{
    return m_operations.keys().toSet();
}

TypeName Type::operationReturnType(const OperationName& name) const
{
    return m_operations.contains(name) ? m_operations[name].first :
        INVALID_VALUE;
}

TypeName Type::rightOperatorType(const OperationName& name) const
{
    return m_operations.contains(name) ? m_operations[name].second :
        "";
}

bool Type::hasIdentity() const
{
    return false;
}

void Type::setIdentity(const Type& identity)
{
    // do nothing
}

TypeName Type::demangledName(const char *name)
{
    char buf[1024];
    unsigned int size=1024;
    int status;
    char* res = abi::__cxa_demangle(name, buf, &size, &status);

    TypeName _name = res;
    //free(res);

    return _name;
}
